<!-- 退货管理--新建退货单 -->
<template>
  <div class="return-order-box hospitalSideNewReturnOrderBox">
    <el-container class="edit-container is-vertical">
      <!-- 基本信息编辑 -->
      <edit-form
        ref="form"
        :form="baseInfo"
        :columns="baseColumns"
      />
      <!-- 产品列表信息及操作 -->
      <div
        class="table-title">
        <div class="title-info">
          <span>已选择产品数量 : {{ totalCount }}</span>
          <span>品种数 :{{ totalVarieties }}</span>
          <span class="order-total-amount">金额合计(元) : <span style="color:red;">
            {{ formatPrice(totalAmount) }}
          </span></span>
        </div>
        <span class="right-button">
          <el-button
            type="danger"
            icon="el-icon-delete"
            @click="batchDelete()"
            size="small">批量删除</el-button>
          <el-button
            type="primary"
            icon="el-icon-edit"
            @click="openAddProductDialog"
            size="small">添加产品</el-button>
        </span>
      </div>
      <!-- 产品列表 -->
      <el-editable
        v-loading="tableLoading"
        :data="returnProductList"
        height="400"
        :row-height="40"
        use-virtual
        :columns="returnProductColumns"
        @selection-change="handleSelectionChange"
      >
        <template
          slot="default-returnNum"
          slot-scope="scope">
          <!-- <el-input-number
            v-model="scope.row.returnNum"
            @change="returnNumChange(scope,$event)"
            :controls="false"
            size="mini"
            :step="1"
            :min="0"
            :max="999999999"
            label="描述文字"
            step-strictly
          /> -->
          <el-input
            v-model="scope.row.returnNum"
            @input="returnNumChange(scope,$event)"
            size="mini"
            :maxlength="8"
          />
        </template>
        <template
          slot="default-action"
          slot-scope="scope">
          <el-button
            size="small"
            @click.stop="deleteOrderProductItem(scope.row)"
            type="text text-danger"
          >删除</el-button>
        </template>
        <template
          slot="default-registrationNumber"
          slot-scope="scope">
          <el-button
            :disabled="!scope.row.registrationNumber||!scope.row.registrationId"
            v-html="regisNoButton(scope.row, 'registration')"
            @click="showPdfRegistion(scope.row.registrationId)"
            type="text"
          />
        </template>
      </el-editable>
      <!-- 选择产品列表 -->
      <add-product
        is-checked
        :key-in="keyIn"
        :key-out="keyOut"
        :registration-number="'registrationNumber'"
        :registration-id="'registrationId'"
        :query-url="activeUrl"
        :search-form-columns="addSearchFormColumns"
        :visible="addProductDialogShow"
        :table-columns="activeAddProductColumns"
        :extra-query="extraQueryData"
        :added-products="returnProductList"
        @cancelDialog="cancelAddSelection"
        @confirmDialog="addSelectionToProductList"
      />
    </el-container>
  </div>
</template>

<script>
import {
  hspReturnProducts, // 医院-退货管理-添加退货产品
  hspReturnGoodsNumber, // 医院-退货管理-院端添加退货单查询发货单号
  hspReturnGoodsSave, // 医院-退货管理-院端新建/保存退货单
  hspReturnGoodsOrderInfo, // 医院-退货管理-订单明细详情
  hspReturnGoodsItemDetail, // 医院-退货管理-订单明细详情带分页
  getAddressListAll, // 收货地址
  partnerList // 客商列表
} from '@const/beforeSettleApi'
import {
  channelCompanyGetList // 客商列表
} from '@const/authCenterApi'
import { returnProductColumns, addProductColumns, baseColumns, addSearchFormColumns, sendThis, addProductColumnsHasReceiveCode } from './const'
import EditForm from '@/moduleComponents/beforeSettle/common/edit-form'
import ElEditable from '@components/el-editable'
import AddProduct from '@/moduleComponents/beforeSettle/common/addProduct'
import { cloneDeep, isObject, hasIn } from 'lodash'
import { getFormatterPrice } from '@const/filter'
import { formatPrice, regisNoButton, showPdfRegistion } from '@const/agencySaas'
export default {
  components: { EditForm, ElEditable, AddProduct },
  data () {
    const columns = cloneDeep(baseColumns)
    columns.splice(3, 1)
    return {
      // 基本信息
      isRequest: true,
      targetPath: '/hospitalSide/returnOrderManage/returnOrder',
      addressList: [],
      orderStatus: null,
      baseInfo: {
        deliveryCompanyName: '',
        deliveryCompanyId: '',
        deliveryOrderId: '',
        deliveryOrderCode: '',
        returnAddressName: '',
        concatMan: '',
        concatPhone: '',
        orderType: 1,
        invoiceFlag: 0
      },
      baseColumns: columns,
      baseMethods: [
        { prop: 'orderType', change: this.changeColumns },
        { prop: 'deliveryOrderCode',
          change: this.changeDeliveryOrderCode,
          attr: { remoteMethod: this.codeRemote }
        },
        { prop: 'deliveryCompanyName',
          change: this.setSupplierInfo,
          attr: { filterMethod: this.getSupplierList }
        },
        { prop: 'returnAddressName',
          select: this.setAddressIdChange,
          attr: { title: true, fetchSuggestions: this.querySearchAddress }
        }
      ],
      // 产品列表
      totalAmount: 0,
      totalCount: 0,
      totalVarieties: 0,
      activeUrl: hspReturnProducts,
      returnProductList: [],
      returnProductColumns,
      activeSelectList: [],
      tableLoading: false,
      // 选择产品
      keyIn: 'orderItemId,batch,udi,receiveCode',
      keyOut: 'oldItemId,batchNumber,udi,receiveCode',
      addProductDialogShow: false,
      addSearchFormColumns,
      addProductColumnsHasReceiveCode,
      addProductColumns
    }
  },
  computed: {
    // 退货类型
    returnType () {
      return ~[1, 2].indexOf(this.baseInfo.orderType) ? 'quality'
        : ~[3, 4].indexOf(this.baseInfo.orderType) ? 'purchase' : 'error'
    },
    id () {
      return this.$route.query.id
    },
    // 编辑是有id
    isEdit () {
      return !!this.id
    },
    fields () {
      const obj = {
        quality: ['deliveryCompanyName', 'deliveryOrderCode'],
        purchase: ['deliveryCompanyName']
      }
      return obj[this.returnType]
    },
    activeAddProductColumns () {
      const obj = {
        quality: this.addProductColumns,
        purchase: this.addProductColumnsHasReceiveCode
      }
      return obj[this.returnType]
    },
    // 其他额外参数
    extraQueryData () {
      const obj = {
        quality: {
          deliverCompanyId: this.baseInfo.deliveryCompanyId,
          id: this.baseInfo.deliveryOrderId,
          orderType: this.baseInfo.orderType
        },
        purchase: {
          deliverCompanyId: this.baseInfo.deliveryCompanyId,
          orderType: this.baseInfo.orderType,
          id: null
        }
      }
      return obj[this.returnType]
    }
  },
  mounted () {
    sendThis(this)
    this.initGlobalBtns()
    if (this.isEdit) {
      this.getBaseAddList()
    } else {
      this.changeColumns(this.returnType)
    }
  },
  methods: {
    formatPrice,
    regisNoButton,
    showPdfRegistion,
    changeDeliveryOrderCode (value, prop, list) {
      list.forEach(({ deliveryCode, id }) => {
        if (Object.is(deliveryCode, value)) {
          const item = {
            deliveryOrderCode: deliveryCode,
            deliveryOrderId: id
          }
          Object.assign(this.baseInfo, item)
        }
      })
      this.returnProductList = []
    },
    initGlobalBtns () {
      // 编辑有返回按钮
      const isEdit = this.isEdit
      let arr = isEdit ? [
        { type: 'common', val: '返回', handle: () => this.$router.go(-1) },
        { type: 'primary', val: '保存草稿', handle: this.handleSave },
        { type: 'primary', val: '提交', handle: this.handleSubmit }
      ] : [
        { type: 'primary', val: '保存草稿', handle: this.handleSave },
        { type: 'primary', val: '提交', handle: this.handleSubmit }
      ]

      const btn = {
        type: 'btn',
        arr: arr
      }
      this.$store.commit('changeLayoutHandle', btn)
    },
    forEachList (target, source, fn) {
      target.forEach(i => {
        source.forEach(j => fn(i, j))
      })
    },
    // 选择方法事件绑定
    bindMethodAddEvent (target = this.baseColumns, methods = this.baseMethods) {
      this.forEachList(target, methods, (i, j) => {
        if (j.prop === i.prop) {
          j.attr && Object.keys(j.attr).forEach(key => {
            this.$set(i.attr, key, j.attr[key])
          })
          j.change && this.$set(i, 'change', j.change)
          j.select && this.$set(i, 'select', j.select)
        }
      })
    },
    // 发票单号查询
    async codeRemote (returnGoodsCode) {
      returnGoodsCode = returnGoodsCode.trim()
      if (!returnGoodsCode) {
        return void 0
      }
      if (!this.baseInfo.deliveryCompanyId) {
        this.baseColumns.forEach(i => {
          if (i.prop === 'deliveryOrderCode') {
            i.options = []
          }
        })
        return void this.$message.warning('请选择配送商')
      }
      const body = {
        companyId: this.baseInfo.deliveryCompanyId,
        orderType: this.baseInfo.orderType, // 1：批发质检退货；2：寄售质检退货"
        returnGoodsCode
      }
      const responseData = await this.$axios.$post(hspReturnGoodsNumber, body)
      const options = hasIn(responseData, 'payload.content') ? (responseData.payload.content || []) : []
      options.forEach(i => {
        i.deliveryOrderCode = i.saleOrderCode
        i.deliveryOrderId = i.saleOrderId
      })
      this.baseColumns.forEach(i => {
        if (i.prop === 'deliveryOrderCode') {
          i.options = options || []
        }
      })
    },
    // 选择退货类型
    changeColumns (val = '') {
      if (!val) {
        return
      }
      // 退货类型 为3，4采购退货时清空发货单号
      if ([3, 4].includes(val)) {
        this.baseInfo.deliveryOrderId = ''
        this.baseInfo.deliveryOrderCode = ''
        this.baseInfo.invoiceFlag = null
      } else {
        this.baseInfo.invoiceFlag = 0
      }
      const typeObj = {
        quality: ['invoiceFlag'],
        purchase: ['deliveryOrderCode']
      }
      const arr = typeObj[this.returnType] || []
      const columns = cloneDeep(baseColumns)
      const source = columns.filter(item => !~arr.indexOf(item.prop))
      this.bindMethodAddEvent(source)
      this.getSupplierList()
      this.$nextTick(() => {
        this.$refs.form.clearValidate()
      })
      this.baseColumns = source
      this.returnProductList = []
    },
    // 选择地址
    setAddressIdChange (item) {
      if (item) {
        this.baseInfo.concatMan = item.linkMan
        this.baseInfo.returnAddressName = item.label
        this.baseInfo.concatPhone = item.linkPhone
      }
    },
    // 搜索地址
    querySearchAddress (queryString, cb, list = this.addressList) {
      const results = queryString ? list.filter(this.createFilter(queryString)) : list
      // 调用 callback 返回建议列表的数据
      cb(results)
    },
    createFilter (queryString) {
      return (item) => {
        // 关于~ 有 ~indexOf(some) 等效于但不等价于 includes(some)  ~a  等价于 -(a+1)
        return (~item.label.toLowerCase().indexOf(queryString.toLowerCase()))
      }
    },
    // 选中供应商
    setSupplierInfo (value, prop, list) {
      list.forEach(({ companyName, companyId, companyBaseInfo }) => {
        if (Object.is(companyName, value)) {
          const item = {
            deliveryCompanyId: companyId
          }
          this.initAddresslist(companyBaseInfo)
          Object.assign(this.baseInfo, item)
        }
      })
      this.baseInfo.returnAddressName = ''
      this.baseInfo.concatMan = ''
      this.baseInfo.concatPhone = ''
      this.baseInfo.deliveryOrderId = ''
      this.baseInfo.deliveryOrderCode = ''
      this.returnProductList = []
    },
    // 地址列表初始化
    initAddresslist (str) {
      const { receiveAddress, linkMan, linkPhone } = JSON.parse(str)
      this.addressList = receiveAddress.map(item => {
        const label = (item.province || '') + (item.city || '') + (item.county || '') + (item.address || '')
        const obj = {
          value: item.id,
          label
        }
        return Object.assign(item, { linkMan, linkPhone, label })
      })
    },
    // 获取客商列表
    async getSupplierList (companyName) {
      const params = {
        companyName,
        partnership: 'provider',
        registered: 2
      }
      const data = await this.$axios.$post(channelCompanyGetList, params)
      if (data.code === '0') {
        const supplierOptions = hasIn(data, 'payload[0]') ? data.payload : []
        this.baseColumns.forEach(i => {
          i.prop === 'deliveryCompanyName' && (i.options = supplierOptions)
        })
      }
    },
    // 编辑时初始化收货地址
    async initAddressListBySupplierList (companyName) {
      const params = {
        companyName,
        partnership: 'provider',
        registered: 2
      }
      const data = await this.$axios.$post(channelCompanyGetList, params)
      if (data.code === '0') {
        const supplierOptions = hasIn(data, 'payload[0]') ? data.payload : []
        const { companyBaseInfo } = supplierOptions[0] || '{}'
        this.initAddresslist(companyBaseInfo)
      }
    },
    // 总价/总数量计算
    getTotal () {
      this.totalAmount = this.returnProductList.reduce((p, q) => {
        return p + +q.returnAmount
      }, 0)
      this.totalCount = this.returnProductList.reduce((p, q) => {
        return p + +q.returnNum
      }, 0)
      const codeArr = [...new Set(this.returnProductList.map(i => i.itemCode))]
      this.totalVarieties = codeArr.length
    },
    // 改变采购数量 处理价格
    returnNumChange (scope, val) {
      let num = parseInt(val)
      isNaN(num) && (num = 0)
      scope.row.returnNum = num
      scope.row.returnAmount = scope.row.returnNum * scope.row.price
      this.getTotal()
    },
    // 处理添加的产品--字段对照
    mapSelectProdList (val) {
      const {
        hspAuthProdId,
        batch,
        deliveryAuthProdId,
        hospitalProductName,
        orderItemId,
        deliveryCode,
        ...rest
      } = val
      return {
        ...rest,
        authProdId: hspAuthProdId,
        batchNumber: batch,
        companyAuthProdId: deliveryAuthProdId,
        nameCn: hospitalProductName,
        oldItemId: orderItemId,
        returnNum: 0,
        upCompanyProdCode: deliveryCode
      }
    },
    // 添加产品
    addSelectionToProductList (list) {
      const keyInArr = this.keyIn.split(',')
      const keyOutArr = this.keyOut.split(',')
      const addedList = []
      // 处理重复的
      this.forEachList(this.returnProductList, list, (i, j) => {
        let flag = keyOutArr.every((key, index) => i[key] === j[keyInArr[index]])
        if (flag) {
          i.num = j.num
          addedList.push(j)
        }
      })
      const filterMotheds = item => !addedList.includes(item)
      // 添加产品字段转换
      const addList = list.filter(filterMotheds).map(this.mapSelectProdList)
      this.returnProductList.unshift(...addList)
      // 统计数量价格（部分字段再次处理）
      this.initReturnOrderListPrice(addList)
      this.addProductDialogShow = false
    },
    cancelAddSelection () {
      this.addProductDialogShow = false
    },
    // 添加产品弹窗
    async openAddProductDialog () {
      const fields = this.fields
      const errs = []
      await this.$refs.form.validateField(fields, (err) => {
        err && errs.push(err)
      })
      if (errs.length) {
        return void this.$message.warning(errs[0])
      }
      this.addProductDialogShow = true
    },
    // 初始化
    initReturnOrderListPrice (list = this.returnProductList) {
      list.forEach(item => {
        item.price = item.price || 0
        this.$set(item, 'returnNum', Math.round(item.returnNum) || 0)
        item.returnAmount = item.returnNum * item.price
      })
      this.getTotal()
    },
    // 删除
    deleteOrderProductItem (row) {
      this.batchDelete([row])
    },
    // 批量删除
    batchDelete (list = this.activeSelectList) {
      const ids = list.map(item => item.authProdId)
      if (!ids.length) {
        this.$message.warning('请选择产品')
        return
      }
      const filterList = this.returnProductList.filter(item => !list.includes(item))
      this.returnProductList = filterList
      this.getTotal()
    },
    handleSelectionChange (val) {
      this.activeSelectList = val
    },
    // 提交或保存
    async request (orderStatus, url = hspReturnGoodsSave) {
      // 防止重复操作
      if (!this.isRequest) {
        return void this.$message.warning('请稍后')
      }
      this.isRequest = false
      try {
        const hspReturnGoodsOrderItemForm = this.returnProductList
        const requestData = {
          ...this.baseInfo,
          orderStatus,
          hspReturnGoodsOrderItemForm
        }
        const responseData = await this.$axios.$post(url, requestData)
        responseData.code === '0' && this.$router.push({
          path: this.targetPath
        })
      } finally {
        this.isRequest = true
      }
    },
    // 提交
    async handleSubmit () {
      // 请填写正确基本信息
      let error = true
      await this.$refs.form.validate(valid => {
        error = !valid
      })
      if (error) {
        return void this.$message.warning('请填写正确基本信息')
      }
      // 请添加产品
      const list = this.returnProductList || []
      if (list.length <= 0) {
        return void this.$message.warning('请添加产品')
      }
      // 退货数量大于可退货数量
      const errorNum = list.filter(item => item.num < item.returnNum)
      if (errorNum.length > 0) {
        return void this.$message.warning('退货数量大于可退货数量')
      }
      // 退货数量不能为零
      const zeroNum = list.filter(item => item.returnNum === 0)
      if (zeroNum.length > 0) {
        return void this.$message.warning('退货数量不能为零')
      }
      this.request(1)
    },
    // 保存
    handleSave () {
      // 只要这几个字段有不为空的就可以保存
      const valids = ['deliveryCompanyName', 'deliveryCompanyId', 'deliveryOrderId', 'returnAddressName', 'concatMan', 'deliveryOrderCode', 'concatPhone']
      const filterBase = valids.filter(valid => this.baseInfo[valid])
      if (filterBase.length <= 0) {
        return void this.$message.warning('草稿不能为空')
      }
      this.request(0)
    },
    // 编辑是获取详情和列表
    async getBaseAddList () {
      const requests = [this.getReturnBaseInfoByid(), this.getReturnListByid()]
      const [base, list] = await Promise.all(requests)
      if (base.code === '0' && list.code === '0') {
        this.baseInfo = base.payload
        // form表单显示项初始化
        this.changeColumns(this.returnType)
        // 地址列表获取
        this.initAddressListBySupplierList(this.baseInfo.deliveryCompanyName)
        this.returnProductList = hasIn(list, 'payload.content') ? list.payload.content : []
        // 统计
        this.initReturnOrderListPrice()
      }
    },
    // 基本详情请求
    getReturnBaseInfoByid () {
      const requestData = {
        id: this.id
      }
      return this.$axios.$post(hspReturnGoodsOrderInfo, requestData)
    },
    // 获取详情产品列表请求
    getReturnListByid () {
      const requestData = {
        id: this.id,
        page: 1,
        pageSize: 10000000
      }
      return this.$axios.$post(hspReturnGoodsItemDetail, requestData)
    }
  }
}
</script>

<style lang="less">
.hospitalSideNewReturnOrderBox {
  .edit-container {
    height: 100%;
  }
  .table-title {
    display: -webkit-flex;
    display: flex;
    justify-content: space-between;
    margin: 10px 0;
    .title-info > span {
      display: inline-block;
      height: 100%;
      margin-right: 20px;
      line-height: 30px;
    }
  }
}
.hospitalSideNewReturnOrderBox .el-form-item {
  display: flex;
  float: left;
  width: 345px !important;
}
</style>
